package com.eternal.main;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.NotificationManager;

import androidx.annotation.RequiresApi;
import androidx.lifecycle.Observer;

import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.Nullable;

import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;

import com.afollestad.materialdialogs.MaterialDialog;
import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.BluetoothStateReceiver;
import com.eternal.base.LogService;
import com.eternal.base.data.LogRepository;
import com.eternal.base.data.RepositoryInjection;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.framework.binding.command.BindingConsumer;
import com.eternal.framework.bus.Messenger;
import com.eternal.framework.bus.RxBus;
import com.eternal.framework.component.BaseActivity;
import com.eternal.framework.utils.KLog;
import com.eternal.framework.utils.Utils;
import com.eternal.main.databinding.ActivityMainBinding;
import com.eternal.main.model.ItemModel;
import com.eternal.main.model.MainModel;
import com.google.android.play.core.appupdate.AppUpdateInfo;
import com.google.android.play.core.appupdate.AppUpdateManager;
import com.google.android.play.core.appupdate.AppUpdateManagerFactory;
import com.google.android.play.core.install.model.AppUpdateType;
import com.google.android.play.core.install.model.UpdateAvailability;
import com.google.android.play.core.tasks.OnCompleteListener;
import com.google.android.play.core.tasks.Task;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Completable;
import io.reactivex.CompletableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.leolin.shortcutbadger.ShortcutBadger;

/**
 * @author Administrator
 */
@Route(path = RouterActivityPath.Main.PAGE_MAIN)
public class MainActivity extends BaseActivity<ActivityMainBinding, MainModel> {
    final int REQUEST_CODE_UPDATE = 9001;
    public static final String SHOW_DELETE_DIALOG = "show delete dialog";
    public static final String ON_ITEM_CLICK = "on_item_click";
    private View tipView = null;
    private MaterialDialog dialog;
    private BluetoothStateReceiver receiver;
    private AppUpdateManager m_appUpdateManager;
    private Disposable timeDispose;

    @Override
    public int initContentView(Bundle savedInstanceState) {
        return R.layout.activity_main;
    }

    @Override
    public int initVariableId() {
        return BR.model;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initModel();
        initMessage();
        intoLog(getIntent());
        registerReceiver();
        appUpdate();
        refershLog();
        //        test();
    }

    private void appUpdate() {
        AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(this);
        m_appUpdateManager = appUpdateManager;
        Task<AppUpdateInfo> appUpdateInfo = appUpdateManager.getAppUpdateInfo();
        appUpdateInfo.addOnCompleteListener(new OnCompleteListener<AppUpdateInfo>() {
            @Override
            public void onComplete(Task task) {
                if (task.isSuccessful()) {
                    // 监听成功，不一定检测到更新
                    AppUpdateInfo it = (AppUpdateInfo) task.getResult();
                    if (it.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
                            && it.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) { // 检测到更新可用且支持即时更新
                        try {
                            // 启动即时更新
                            m_appUpdateManager.startUpdateFlowForResult(it, AppUpdateType.IMMEDIATE, MainActivity.this, REQUEST_CODE_UPDATE);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    // 监听失败
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_UPDATE) {
            if (resultCode == Activity.RESULT_OK) {
                KLog.w("GPUpdate", "应用内更新成功");
            } else if (resultCode == Activity.RESULT_CANCELED) {
                KLog.w("GPUpdate", "应用内更新, 用户取消");
            } else {
                KLog.w("GPUpdate", "应用内更新，遇到错误");
            }
        }
    }

    private void registerReceiver() {
        if (receiver == null) {
            receiver = new BluetoothStateReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//            filter.addAction("android.bluetooth.BluetoothAdapter.STATE_OFF");
//            filter.addAction("android.bluetooth.BluetoothAdapter.STATE_ON");
            registerReceiver(receiver, filter);

        }
    }

    private void refershLog() {
        if (timeDispose == null || timeDispose.isDisposed()) {
            RxBus.getDefault().toObservable(Long.class)
                    .flatMapCompletable(new Function<Long, CompletableSource>() {
                        @Override
                        public CompletableSource apply(Long aLong) throws Exception {
                            if (aLong == 200) {
                                Completable completable = null;
                                for (int i = 0; i < viewModel.items.size(); i++) {
                                    completable = LogService.getInstance().addRefresh(viewModel.items.get(i).getMac(), viewModel.items.get(i).getDeviceInfo().port).subscribeOn(Schedulers.io());
                                    return completable == null ? Completable.complete() : completable;
                                }
                                return completable;
                            } else {
                                return Completable.complete();
                            }
                        }
                    }).subscribeOn(Schedulers.io()).subscribe();
        }
    }

    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            RxBus.getDefault().post(200L);
            handler.postDelayed(this, 3000);
        }
    };

    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    protected void onResume() {
        if (!handler.hasCallbacks(runnable)) {
            handler.postDelayed(runnable, 3000);
        }
        super.onResume();
    }


    private void unregisterReceiver() {
        if (receiver != null) {
            unregisterReceiver(receiver);
            receiver = null;
        }
    }

    @SuppressLint("CheckResult")
    private void intoLog(Intent intent) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancelAll();
        ShortcutBadger.removeCount(this);
        LogRepository repository = RepositoryInjection.providerLogRepository();
        repository.clearNotify();
        if (ActivityEvent.ACTION_LOG.equals(intent.getAction())) {
            String mac = intent.getStringExtra(ActivityEvent.DEVICE_MAC);
            final Postcard postcard = ARouter.getInstance().build(RouterActivityPath.Detail.PAGE_DETAIL)
                    .withAction(ActivityEvent.ACTION_LOG).withString(ActivityEvent.DEVICE_MAC, mac);
            if (!repository.isConnect(mac)) {
                repository.clearNotify();
                repository.getDeviceTime(mac)
                        .compose(this.<Long>bindToLifecycle())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                String time = Utils.getString(R.string.tip_last, ProtocolTransformer.getTime(aLong));
                                postcard.withString(ActivityEvent.DEVICE_TIME, time);
                                postcard.navigation(MainActivity.this);
                            }
                        });


            } else {
                postcard.navigation(this);
            }
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
//        test();
        super.onNewIntent(intent);
        String action = intent.getAction();
        if (ActivityEvent.ACTION_ADD_DEVICE.equals(action)) {
            int index = intent.getIntExtra(ActivityEvent.DEVICE_INDEX, -1);
            viewModel.requestConnect(index);
        } else if (ActivityEvent.ACTION_DELETE_DEVICE.equals(action)) {
            viewModel.remove(intent.getStringExtra(ActivityEvent.DEVICE_MAC));
        } else {
            intoLog(intent);
        }
    }

    private void initModel() {
        viewModel.init(RepositoryInjection.providerDeviceRepository());
        viewModel.showTip.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean result) {
                if (result == null) {
                    return;
                }
                if (result) {
                    binding.layoutDevice.setVisibility(View.GONE);
                    tipView = LayoutInflater.from(getApplication()).inflate(R.layout.first_tip, binding.layoutMain, false);
                    binding.layoutMain.addView(tipView);
                } else if (tipView != null) {
                    binding.layoutMain.removeView(tipView);
                    binding.layoutDevice.setVisibility(View.VISIBLE);
                    tipView = null;
                }
            }
        });
    }

    private void initMessage() {
        Messenger.getDefault().register(this, SHOW_DELETE_DIALOG, ItemModel.class, new BindingConsumer<ItemModel>() {
            @Override
            public void call(ItemModel itemModel) {
                binding.layoutDevice.closeMenu();
                showDelete(itemModel);
            }
        });
        Messenger.getDefault().register(this, ON_ITEM_CLICK, ItemModel.class, new BindingConsumer<ItemModel>() {
            @Override
            public void call(ItemModel itemModel) {
                viewModel.setSelectedDevice(itemModel.getDeviceInfo());
            }
        });
    }

    private void showDelete(final ItemModel item) {
        View view;
        if (dialog == null) {
            view = LayoutInflater.from(this).inflate(com.eternal.res.R.layout.reconfirm_dialog, null, false);
            dialog = new MaterialDialog.Builder(this)
                    .backgroundColor(0x00ffffff)
                    .customView(view, false)
                    .build();
            view.findViewById(com.eternal.res.R.id.tv_cancel)
                    .setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            dialog.dismiss();
                        }
                    });
        }
        view = dialog.getCustomView();
        view.findViewById(com.eternal.res.R.id.tv_confirm)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        binding.layoutDevice.closeMenu();
                        viewModel.remove(item);
                        dialog.dismiss();
                    }
                });
        dialog.show();
    }

    @Override
    protected void onPause() {
        viewModel.save();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        viewModel.save();
        unregisterReceiver();
        viewModel.stopScan();
        Messenger.getDefault().unregister(this);
        if (timeDispose != null) {
            timeDispose.dispose();
            timeDispose = null;
        }
        if (handler != null) {
            handler.removeCallbacks(runnable);
            handler = null;
        }
        super.onDestroy();
    }

    public void test() {
//        Toast toast=new Toast(this);
//        View notify=LayoutInflater.from(this).inflate(R.layout.pop_notification, null);
//        toast.setView(notify);
//        toast.setGravity(Gravity.TOP|Gravity.FILL_HORIZONTAL, 0, 0);
//        ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ConvertUtils.dp2px(95));
//        notify.setLayoutParams(params);
//        toast.setMargin(ConvertUtils.dp2px(15), 0);
//        toast.setDuration(Toast.LENGTH_SHORT);
//        try{
//            Object mTN=getField(toast, "mTN");
//            if(mTN!=null){
//                Object mParams=getField(mTN, "mParams");
//                if(mParams instanceof WindowManager.LayoutParams){
//                    WindowManager.LayoutParams p= (WindowManager.LayoutParams) mParams;
//                    p.flags=WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
//                    p.height=ConvertUtils.dp2px(95);
//                    p.windowAnimations=R.style.Notify;
//                }
//            }
//        }catch (IllegalAccessException e) {
//            e.printStackTrace();
//        } catch (NoSuchFieldException e) {
//            e.printStackTrace();
//        }
//        toast.show();
    }

//    private static Object getField(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
//        Field field = object.getClass().getDeclaredField(fieldName);
//        if (field != null) {
//            field.setAccessible(true);
//            return field.get(object);
//        }
//        return null;
//    }
}
